﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.ObjectMapping;
using Abp.Runtime.Caching;
using AutoMapper.QueryableExtensions;
using FwProject.Authorization;
using FwProject.Authorization.Users;
using FwProject.Core.FactoryInfo;
using FwProject.FactoryInfo.Dto;
using FwProject.Manager;
using X.PagedList;

namespace FwProject.FactoryInfo
{
    [AbpAuthorize]
    public class FactoryNameInfoAppService : FwProjectAppServiceBase, IFactoryNameInfoAppService
    {
        public readonly IRepository<FactoryNameInfo, Guid> _repositoryFactoryNameInfo;
        private readonly FactoryNameInfoManager _factoryManager;
        public readonly ICacheManager _catchmanager;
        public IGuidGenerator _guid { get; set; }
        public IObjectMapper _map { get; set; }

        public FactoryNameInfoAppService(
            ICacheManager catchmanager, IRepository<FactoryNameInfo, Guid> repositoryFactoryNameInfo,
            FactoryNameInfoManager factoryManager)
        {
            _catchmanager = catchmanager;
            _repositoryFactoryNameInfo = repositoryFactoryNameInfo;
            _factoryManager = factoryManager;
            _map = NullObjectMapper.Instance;
        }
        /// <summary>
        /// 添加一个工厂
        /// </summary>
        /// <returns>The create.</returns>
        /// <param name="input">Input.</param>
        public async Task<Guid> Create(FactoryNameInfoInput input)
        {
            var model = _map.Map<FactoryNameInfo>(input);
            model.Id = _guid.Create();
            return await _factoryManager.CreateFactory(model);
        }

        /// <summary>
        /// 获取一个工厂信息
        /// </summary>
        /// <returns>The by identifier async.</returns>
        /// <param name="id">Identifier.</param>
        public async Task<FactoryNameInfoDto> GetByIdAsync(Guid id)
        {
            var model = await _repositoryFactoryNameInfo.GetAsync(id);
            return _map.Map<FactoryNameInfoDto>(model);

        }
        /// <summary>
        /// 返回工厂列表
        /// </summary>
        /// <returns>The restaurant paged list async.</returns>
        /// <param name="汽车编号">Page index.</param>
        public async Task<IPagedList<FactoryNameInfoDto>> GetPagedListAsync(int pageIdx, int pageSize, DateTime? begindateTime, DateTime? enddatetime, string keyword)
        {
            var listmodel = (await GetCache).AsQueryable();
            if (!string.IsNullOrEmpty(keyword))
                listmodel = listmodel.Where(o => o.FactoryName.Contains(keyword));

            if (begindateTime != null)
                listmodel.Where(o => o.CreationTime >= begindateTime);

            if (enddatetime != null)
                listmodel.Where(o => o.CreationTime <= enddatetime);

            return await listmodel.ProjectTo<FactoryNameInfoDto>().ToPagedListAsync(pageIdx, pageSize);

        }


        public async Task<List<FactoryNameInfoDto>> GetAllAsync(string keyword)
        {
            var query = (await GetCache).AsQueryable();

            if (!IsGranted(PermissionNames.Factory_All))
            {
                var user = await base.GetCurrentUserAsync();
                query = query.Where(o => o.Id == user.FactoryinfoId);
            }

            if (!string.IsNullOrWhiteSpace(keyword))
            {
                query = query.Where(o => o.FactoryName.Contains(keyword));
            }

            return await query.ProjectTo<FactoryNameInfoDto>().ToListAsync();
        }

        public async Task<List<FactoryJSTreeOutputDto>> GetFactoryTreeAsync(bool isType)
        {
            var query = (await GetCache).AsQueryable();
            if (!IsGranted(PermissionNames.Factory_All))
            {
                var user = await base.GetCurrentUserAsync();
                query = query.Where(o => o.Id == user.FactoryinfoId);
            }
            var factorys = query.ToList();
            int tid = 0;
            List<FactoryJSTreeOutputDto> list = new List<FactoryJSTreeOutputDto>();
            factorys.ForEach(o =>
            {
                FactoryJSTreeOutputDto tree = new FactoryJSTreeOutputDto();
                tree.Type = "GC";
                tree.Id = o.Id.ToString();
                tree.FactoryId = o.Id;
                tree.Text = o.FactoryName;
                if (isType)
                {
                    tree.Children = new List<FactoryJSTreeOutputDto>()
                    {
                        new FactoryJSTreeOutputDto(){
                        Id="G_"+(tid++),
                        FactoryId = o.Id,
                        Text = "工厂老板",
                        Type = EmployeeType.工厂老板.ToString()
                    },
                        new FactoryJSTreeOutputDto()
                    {
                        Id = "Y_" + (tid++),
                         FactoryId = o.Id,
                        Text = "员工类型",
                        Type = EmployeeType.员工类型.ToString()
                    },
                        new FactoryJSTreeOutputDto()
                    {
                        Id = "S_" + (tid++),
                         FactoryId = o.Id,
                        Text = "司机类型",
                        Type = EmployeeType.司机类型.ToString()
                    },
                        new FactoryJSTreeOutputDto()
                    {
                        Id = "C_" + (tid++),
                        FactoryId = o.Id,
                        Text = "餐厅老板类型",
                        Type = EmployeeType.餐厅老板类型.ToString()
                    }
                    };
                }
                list.Add(tree);
            });
            return list;
        }


        /// <summary>
        /// 修改工厂信息
        /// </summary>
        /// <returns>The update.</returns>
        /// <param name="id">Identifier.</param>
        /// <param name="input">Input.</param>
        public async Task Update(Guid id, FactoryNameInfoInput input)
        {
            var model = await _repositoryFactoryNameInfo.GetAsync(id);
            model = _map.Map(input, model);
            await _factoryManager.UpdateFactory(model);

        }

        /// <summary>
        /// 删除工厂
        /// </summary>
        /// <param name="id"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task Delete(Guid id)
        {
            var model = await _repositoryFactoryNameInfo.GetAsync(id);
            await _repositoryFactoryNameInfo.DeleteAsync(model);

        }

        private Task<List<FactoryNameInfo>> GetCache
        {
            get
            {
                ICache cache = _catchmanager.GetCache(nameof(FactoryNameInfo));
                return cache.GetAsync("list", async () => await _repositoryFactoryNameInfo.GetAllListAsync());
            }

        }
    }
}
